package com.lottery.pay.service.impl;

import com.alibaba.fastjson.JSON;
import com.lottery.common.contants.Constants;
import com.lottery.common.entity.PaymentRecords;
import com.lottery.pay.Constants.WeixinConstant;
import com.lottery.pay.Model.weixin.OrderParam;
import com.lottery.pay.Model.weixin.PaymentParam;
import com.lottery.pay.Utils.wxUtil.HttpRequest;
import com.lottery.pay.Utils.wxUtil.MainUtil;
import com.lottery.pay.service.PaymentRecordsService;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TreeMap;

/**
 * 微信支付
 */
@Service
//@Configuration
//@ImportResource("classpath:spring-mvc.xml")
public class PaymentService {
	public static final Logger logger = LoggerFactory.getLogger(PaymentService.class);

	@Autowired
	private PaymentRecordsService prs;
	/**
	 * 统一下单接口
	 */
	public Object payoff(String body, String out_trade_no,
                         Integer total_fee, String openid, String spbill_create_ip, String payType) {
		logger.info("PaymentService payoff in");
		Date date=new Date();
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
		String startTime=format.format(date);
		String appId=WeixinConstant.APP_ID;
		if (!(payType.equals("JSAPI")||payType.equals("MWEB"))){
			appId=WeixinConstant.APP_APPID;
			openid=null;
		}

		OrderParam orderParam = new OrderParam(appId,WeixinConstant.MCH_ID, body, body,
				body, out_trade_no, total_fee.toString(), spbill_create_ip, body,
				payType, out_trade_no, openid ,startTime);
		// object转化为TreeMap
		TreeMap<Object, Object> treeMap = MainUtil.objectToTreeMap(orderParam);
		// 生成签名
		String sign = MainUtil.creatSign(treeMap,  WeixinConstant.API_KEY);
		orderParam.setSign(sign);
		String xmlString = orderParam.toXmlString(orderParam);
		if (payType.equals("JSAPI")){
			xmlString = orderParam.toJsXmlString(orderParam);
		}
		logger.info("weixin payoff orderXml={}", xmlString);
//		Integer count=prs.insertSelective(new PaymentRecords(Constants.TYPE_ONE,1,out_trade_no,total_fee,Constants.TYPE_ONE));
//		if (count==0){
//			return null;
//		}
		String response = HttpRequest.sendPost(WeixinConstant.PAYOFF_PATH,
				xmlString);
		logger.info("weixin payoff response={}", response);

		// 解析出prepay_id
		PaymentParam paymentParam = null;
		try {
			Document document = DocumentHelper.parseText(response);
			Element rootElement = document.getRootElement();
			String prepay_id = rootElement.elementText("prepay_id");
			String code_url = rootElement.elementText("code_url");
			String mweb_url = rootElement.elementText("mweb_url");
			if (prepay_id == null) {
				return response;
			}
			if (payType.equals("APP")){
				paymentParam = getAppParam(prepay_id,code_url,mweb_url);
			}else{
				paymentParam = getWebParam(prepay_id,code_url,mweb_url);

			}
		} catch (DocumentException e) {
			prs.updateByPrimaryKeySelective(new PaymentRecords(out_trade_no,Constants.TYPE_SEVEN));
			logger.info("返回信息错误");
			e.printStackTrace();
		}
		logger.info("weixin payoff param={}", JSON.toJSONString(paymentParam));
		return paymentParam;
	}

	//微信app支付参数
	public PaymentParam getAppParam(String prepay_id, String code_url, String mweb_url){
		PaymentParam paymentParam = null;
		paymentParam = new PaymentParam(WeixinConstant.APP_APPID,WeixinConstant.MCH_ID, prepay_id,"Sign=WXPay",code_url,mweb_url);
		int payType = 0; // 支付类型 0:微信公众号支付 1:APP支付
		// 生成签名
		TreeMap<Object, Object> treeMap1 = new TreeMap<Object, Object>();
		treeMap1.put("appid", paymentParam.getAppId()); // 公众账号ID
		treeMap1.put("partnerid", paymentParam.getPartnerId()); // 商户号ID
		treeMap1.put("prepayid", paymentParam.getPrepayId()); //
		treeMap1.put("timestamp", String.valueOf(paymentParam.getTimeStamp()));// 取当前时间，并精确到秒
		treeMap1.put("noncestr", paymentParam.getNonceStr());// 生成随机字符串
		treeMap1.put("package", paymentParam.getPackageValue());
//		treeMap1.put("signType", paymentParam.getSignType());
//		treeMap1.put("codeUrl", paymentParam.getCodeUrl());
		String paymentSign = MainUtil.creatSign(treeMap1, WeixinConstant.API_KEY);
		paymentParam.setPaySign(paymentSign);
		logger.info("weixin payoff param={}", JSON.toJSONString(paymentParam));
		return  paymentParam;
	}

	//微信web支付参数
	public PaymentParam getWebParam(String prepay_id,String code_url,String mweb_url){
		PaymentParam paymentParam = null;
		paymentParam = new PaymentParam(WeixinConstant.APP_ID, prepay_id,code_url,mweb_url);
		int payType = 0; // 支付类型 0:微信公众号支付 1:APP支付
		// 生成签名
		TreeMap<Object, Object> treeMap1 = new TreeMap<Object, Object>();
		treeMap1.put("appId", paymentParam.getAppId()); // 公众账号ID
		treeMap1.put("timeStamp", paymentParam.getTimeStamp());// 取当前时间，并精确到秒
		treeMap1.put("nonceStr", paymentParam.getNonceStr());// 生成随机字符串
		treeMap1.put("package", paymentParam.getPackageValue());
		treeMap1.put("signType", paymentParam.getSignType());
//		treeMap1.put("codeUrl", paymentParam.getCodeUrl());
		String paymentSign = MainUtil.creatSign(treeMap1,WeixinConstant.API_KEY);
		paymentParam.setPaySign(paymentSign);
		logger.info("weixin payoff param={}", JSON.toJSONString(paymentParam));
		return  paymentParam;
	}
	/**
	 * 支付成功，对订单进行处理
	 */
	public boolean orderProcessing(String out_trade_no) {
		return true;
	}

	/**
	 * 处理充值参数
	 */
	@Transactional
	public boolean rechargeProcessing(String transaction_id) {
		return true;
	}


	/**
	 * 生成开始时间
	 */
	public String setTime_start(Date date) {
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
		return format.format(date);
	}


	/**
	 * 生成结束时间
	 *
	 */
	public String setTime_expire(int time, String time_start) {
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
		try {
			Date date = format.parse(time_start);
			Long nowTime = date.getTime();
			Long endTime = nowTime + time * 1000;
			Date endDate = new Date(endTime);
			return format.format(endDate);
		} catch (ParseException e) {
			e.printStackTrace();
			Long nowTime = System.currentTimeMillis();
			Long endTime = nowTime + time * 1000;
			Date endDate = new Date(endTime);
			return format.format(endDate);
		}
	}

}
